package com.amin.concurrent;

import java.io.File;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.junit.Test;

import com.amin.concurrent.ExecutorServiceDemo.ThreadRunner;

public class BlockingQueueTest {

	@Test
	public void ArrayBlockingQueueTest() throws Exception {
		BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1024);
		queue.put("1");
		System.out.println(queue.take());
	}

	@Test
	public void usedExceptionTest() {// 抛异常 add/remove/element检查
		BlockingQueue<Integer> que = new ArrayBlockingQueue<Integer>(2);
		que.add(1);
		que.add(2);
		try {
			que.add(3);
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			que.remove();
			que.remove();
			que.remove();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	// 容量为2的队列 模拟阻塞效果
	public static BlockingQueue<Integer> que = new ArrayBlockingQueue<Integer>(3);
	/**
	 * 队列MQtestDemo
	 */
	@Test
	public void forBlockingQueueTest() {
		try {
			int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 1, 2, 1, 2, 3, 4,
					5, 6, 7, 8, 9, 0, 10, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 1, 2 };
			ExecutorService es = new ThreadPoolExecutor(5, 10, 10000, TimeUnit.MILLISECONDS,
					new ArrayBlockingQueue<Runnable>(5), new RejectedExecutionHandler() {
						public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
							System.out.println("当前线程池已满");

						}
					});

			for (int i = 0; i < arr.length; i++) {
				que.put(arr[i]);
				es.submit(new RunTest(que));
			}
			
			es.shutdown();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testTedingzhi() {// offer/poll/peek检查
		BlockingQueue que = new ArrayBlockingQueue<>(2);
		que.offer(1);
		que.offer(1);
		System.out.println(que.offer(2));
	}

	@Test
	public void blockTest() throws Exception {// put/take
		BlockingQueue que = new ArrayBlockingQueue(2);
		que.put(1);
		que.put(2);
		que.put(3);
	}

	@Test
	public void waitTime() throws Exception {
		BlockingQueue que = new ArrayBlockingQueue(2);
		que.offer(1);
		que.offer(1);
		que.offer(1, 1, TimeUnit.SECONDS);// T
	}
}

class RunTest extends Thread {
	public BlockingQueue<Integer> bq;
	
	public RunTest(BlockingQueue<Integer> bq){
		this.bq = bq;
	}
	
	@Override
	public void run() {
		try {
			int take = bq.take();
			System.out.println("执行线程 ----"+ File.separator + take);
			sleep(take * 1000L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}